package com.sh.rbac.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sh.rbac.domain.converter.JobConverter;
import com.sh.rbac.domain.dto.job.JobQueryDTO;
import com.sh.rbac.domain.dto.job.JobSaveDTO;
import com.sh.rbac.domain.dto.job.JobUpdateDTO;
import com.sh.rbac.domain.entity.Job;
import com.sh.rbac.domain.vo.job.JobVO;
import com.sh.rbac.exception.CustomException;
import com.sh.rbac.mapper.JobMapper;
import com.sh.rbac.service.JobService;
import com.sh.rbac.utils.TaskUtils;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.Collection;

/**
 * @author lucky
 * @description 针对表【sys_job(定时任务表)】的数据库操作Service实现
 * @createDate 2024-08-05 17:31:34
 */
@Slf4j
@Service
public class JobServiceImpl extends ServiceImpl<JobMapper, Job>
        implements JobService {

    @Autowired
    private Scheduler scheduler;

    @Override
    public Boolean runJob(Long id) {
        Job job = super.getById(id);
        job.setMisfirePolicy(2);

        try {
            scheduler.triggerJob(TaskUtils.getJobKey(job));
        } catch (Exception e) {
            log.error("任务执行一次失败 ===> {}", e.getMessage());
            return false;
        }

        return super.updateById(job);
    }

    @Override
    public Page<JobVO> getPage(Long current, Long limit, JobQueryDTO jobQueryDTO) {
        Page<Job> page = new Page<>(current, limit);

        String jobName = jobQueryDTO.getJobName();
        String jobGroup = jobQueryDTO.getJobGroup();
        Integer status = jobQueryDTO.getStatus();

        // 构造条件
        LambdaQueryWrapper<Job> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StrUtil.isNotBlank(jobName), Job::getJobName, jobName)
                .like(StrUtil.isNotBlank(jobGroup), Job::getJobGroup, jobGroup)
                .eq(status != null, Job::getStatus, status);

        // 查询
        Page<Job> oldJobPage = super.page(page, wrapper);

        // 数据转换
        Page<JobVO> newJobPage = new Page<>();
        newJobPage.setTotal(oldJobPage.getTotal());
        newJobPage.setSize(oldJobPage.getSize());
        newJobPage.setCurrent(oldJobPage.getCurrent());
        newJobPage.setRecords(JobConverter.INSTANCE.toVoList(oldJobPage.getRecords()));
        newJobPage.setPages(oldJobPage.getPages());

        return newJobPage;
    }

    @Override
    public Boolean save(JobSaveDTO jobSaveDTO) {
        Job job = JobConverter.INSTANCE.toEntity(jobSaveDTO);

        if (job.getMisfirePolicy() == 1) {
            job.setStatus(0);
        } else if (job.getMisfirePolicy() == 2) {
            job.setStatus(2);
        } else {
            job.setStatus(1);
        }

        // 创建任务
        TaskUtils.createJob(job, scheduler);

        return super.save(job);
    }

    @Override
    public Boolean updateById(JobUpdateDTO jobUpdateDTO) {
        Job job = JobConverter.INSTANCE.toEntity(jobUpdateDTO);

        if (job.getMisfirePolicy() == 1) {
            job.setStatus(0);
        } else if (job.getMisfirePolicy() == 2) {
            job.setStatus(2);
        } else {
            job.setStatus(1);
        }

        // 创建任务
        TaskUtils.createJob(job, scheduler);

        return super.updateById(job);
    }

    @Override
    public Boolean startJob(Long id) {
        Job job = super.getById(id);

        if(job.getStatus() == 0){
            throw new CustomException("重复启动");
        }

        job.setMisfirePolicy(1);
        job.setStatus(0);

        try {
            scheduler.resumeJob(TaskUtils.getJobKey(job));
        } catch (Exception e) {
            log.error("定时任务启动失败 ===> {}", e.getMessage());
            return false;
        }

        return super.updateById(job);
    }

    @Override
    public Boolean pauseJob(Long id) {
        Job job = super.getById(id);
        job.setMisfirePolicy(2);
        job.setStatus(2);

        try {
            scheduler.pauseJob(TaskUtils.getJobKey(job));
        } catch (Exception e) {
            log.error("定时任务暂停失败 ===> {}", e.getMessage());
            return false;
        }

        return super.updateById(job);
    }


    @Override
    public boolean removeById(Serializable id) {
        Job job = super.getById(id);

        try {
            scheduler.deleteJob(TaskUtils.getJobKey(job));
        } catch (Exception e) {
            log.error("定时任务删除失败 ===> {}", e.getMessage());
            return false;
        }
        return baseMapper.deleteById(id) > 0;
    }

    @Override
    public boolean removeBatchByIds(Collection<?> list) {
        try {
            list.forEach(id -> super.removeById((Serializable) id));
        } catch (Exception e) {
            log.error("定时任务删除失败 ===> {}", e.getMessage());
            return false;
        }

        return true;
    }
}




